#pragma once

#include <hash_set>
#include "../common/tcp_base_common_type.h"
#include "../packet/recv_packet.h"

//////////////////////////////////////////////////////////////////////////
//
class tcp_server_base_t
{
public:
	typedef connection_t::pointer connection_ptr;
	typedef std::map<connection_t*, connection_ptr> connections_t;
	typedef std::tr1::function<bool(connection_t*, recv_packet_t&)> packet_dispatcher;
	typedef std::map< packet_id_t, packet_dispatcher > packet_dispatchers_t;
	typedef std::function<void(connection_t const*)> connection_event_t;
	typedef std::vector<connection_event_t> connection_event_callbacks_t;

	tcp_server_base_t(tcp_base_port_t const& port);
	virtual ~tcp_server_base_t();

	void send(connection_t const * conn, umtl::memory_stream& stream);

	void register_on_accept_callback(connection_event_t const& callback);
	void register_on_recv_callback(connection_event_t const& callback);
	void register_on_close_callback(connection_event_t const& callback);

	void register_dispatcher(packet_id_t packet_id, packet_dispatcher const& dispatcher);

protected:
	virtual void on_accept(connection_t const* conn);
	virtual void on_disconnect(connection_t const* conn);

private:
	tcp_base_port_t port_;
	umtl::tcp_server server_;
	connections_t connections_;
	packet_dispatchers_t packet_dispatchers_;
	connection_event_callbacks_t on_accept_callbacks_;
	connection_event_callbacks_t on_recv_callbacks_;
	connection_event_callbacks_t on_close_callbacks_;

	
	tcp_server_base_t(tcp_server_base_t const&);

	void accepted(connection_t* conn);
	void recved(connection_t* conn, char const * packet, size_t size);
	void disconnected(connection_t* conn);

	void process_packet( connection_t* conn, recv_packet_t & packet );
};

//////////////////////////////////////////////////////////////////////////